/**
 * 
 */

import hce.HceService
import hce.core.composition.*

import hce.core.support.identification.UIDBasedID

import com.thoughtworks.xstream.XStream

import org.codehaus.groovy.grails.commons.GrailsApplication

import converters.DateConverter

import hce.core.data_types.encapsulated.DvMultimedia

// TEST
import util.HCESession


/**
 * @author Pablo Pazos Gutierrez (pablo.swp@gmail.com)
 *
 */
class TraumaController {

    def hceService
    def demographicService
    
    def index = {

       redirect(action:'list')
       //redirect(action:'create')
    }
    
    // TODO: vista
    // Pantalla 2.1- Escritorio Medico-Administrativo
    def list = {
        // TODO: poner el usuario en sesion cuando halla login.
        // FIXME: esto deberia hacerse con filters
       if (!session.traumaContext)
       {
           session.traumaContext = new HCESession(
                                 userId: 1234 // FIXME: depende del login
                               )
       }
       else { // deselecciona el episodio que este seleccionado
           session.traumaContext.episodioId = null
       }
    
        def compos = Composition.list()
        return [compositions:compos]
    }
    
    
    // Pantalla 3.2- Crear Episodio
    // Puede venir un patientId si creo el episodio para un paciente desde admision.
    def create = {
   
        println "Create: " + params
        if (params.doit)
        {
            def startDate = DateConverter.iso8601ExtendedDateTimeFromParams( params, 'startDate_' )
            
            println "Startdate: " + startDate
            
            def composition = hceService.createComposition( startDate, params.otherContext )
            //def composition = hceService.createComposition( params.startDate, params.otherContext )
           
            // TODO: verificar si se crea para un paciente:
            // - buscarlo por id en el servicio demografico
            // - asociarlo como subject de la composition
            // - guardar todo
            
            // FIXME: si hay un paciente seleccionado no deberia venir en params,
            //        deberia estar en HCESession.
            if (params.root && params.extension) // si viene el id del paciente
            {
                println "Se crea un episodio para el paciente seleccionado"
                def partySelf = hceService.createPatientPartysSelf(params.root, params.extension)
                def participation = hceService.createParticipationToPerformer( partySelf )
                composition.context.addToParticipations( participation )
            }
            
            //XStream xstream = new XStream()
            //render( text: xstream.toXML(composition), contentType:'text/xml' )
            if (!composition.save())
            {
                println "Error: " + composition.errors
            }
            
            redirect(action:'list')
            return
        }
    }
    
    def show = {
       
       // TODO: poner en sesion el episodio que se esta viendo
       println "Show: " + params
       
       
       // Si expira la sesion tengo que volver al listado para crearla de nuevo
       // FIXME: esto deberia estar en un pre-filter
       if (!session.traumaContext)
       {
           redirect(action:'list')
           return
       }
       
       // Actualizacion de contexto, esta seleccionado un unico episodio
       session.traumaContext.episodioId = Integer.parseInt(params.id)
       
       
       def composition = Composition.get( params.id )
       
       // FIXME:
       // La primera vez que se muestra luego de seleccionar un paciente, esto da null.
       // Ver si es un tema de la carga lazy de las participations y si se resuelve con carga eager.
       def patient = hceService.getPatientFromComposition( composition )
       
       /*
       // Si la composition tiene un paciente asignado (tiene un ID en
       // context.participations.PartySelf), con ese ID le pido al 
       // servicio demografico que me de la info del paciente.
       def participations = composition.context.participations
       def patientParticipation = null
       if ( participations.size() > 0 )
       {
          patientParticipation = participations.find{ it.function.value == 'subject of care' }
       }
       
       def patient = null
       if (patientParticipation)
       {
          def patientProxy = patientParticipation.performer
          
          // List<Person> findPersonById( UIDBasedID id )
          def patients = demographicService.findPersonById( patientProxy.externalRef.objectId )
          
          if (patients.size() == 1) patient = patients[0]
          else
          {
              println patients
              throw new Exception('Se encuentran: ' + patients.size() + ' pacientes a partir del ID: '+ patientProxy.externalRef.objectId )
          }
          
          if (!patientProxy.externalRef.objectId instanceof UIDBasedID)
             throw new Exception('Se espera un UIDBasedID y el tipo del id es: ' + patientProxy.externalRef.objectId.getClass())
          
       }
       */

       // patient puede ser null si todavia no se selecciono un paciente para el episodio,
       // p.e. si la atencion es de urgencia, se atiente primero y luego se identifica al paciente.
       [composition: composition, patient:patient, episodeId:session.traumaContext?.episodioId]
    }
    
    
    // TODO: vista listando links a templates segun config.
    // Pantalla 5.1- Registro Clinico
    def registroClinico = {
            
       //println grailsApplication.config.hce.emergencia.compositions.getClass() // ConfigObject extends LinkedHashMap
        
       // DEBE haber un episodio seleccionado para poder asociar el registro clinico.
       if (!session.traumaContext?.episodioId)
       {
           flash.message = 'trauma.list.error.noEpisodeSelected'
           redirect(controller:'trauma', action:'list')
           return
       }
        
       def sections = [:]
       grailsApplication.config.hce.emergencia.compositions.trauma.keySet().each { sectionPrefix ->
           grailsApplication.config.hce.emergencia.compositions.trauma."$sectionPrefix".each { section ->
            
               if (!sections[sectionPrefix]) sections[sectionPrefix] = []
             
               // Tiro la lista de esto para cada "section prefix" que son los templates
               // de las subsecciones de la seccion principal.
               //println sectionPrefix + "-" + section
               sections[sectionPrefix] << sectionPrefix + "-" + section
           }
       }
       
       def composition = Composition.get( session.traumaContext?.episodioId )
       def patient = hceService.getPatientFromComposition( composition )
         
       return [sections:sections, episodeId:session.traumaContext?.episodioId, patient:patient]
    }
    
    def registroClinico2 = {
    
        def section = params.section
        def firstSubSection = grailsApplication.config.hce.emergencia.compositions.trauma."$section"[0]
        
        //println "section: " + section
        //println "firstSubSection: " + firstSubSection
        
        redirect(controller: 'guiGen',
                 action: 'generarTemplate',
                 params: [templateId: section+'-'+firstSubSection, episodeId: session.traumaContext?.episodioId])
    }
    
       
    def fetch_mm = {
        
        response.setHeader("Cache-Control", "no-store")
        response.setHeader("Pragma", "no-cache")
        response.setDateHeader("Expires", 0)
          
        def image = DvMultimedia.get( params.id )
            
        if (image)
        {
            response.setContentType(image.mediaType.codeString)
            response.getOutputStream().write(image.data) // con byte[]   
            
            response.outputStream.flush()
            response.outputStream.close()
        }

        return null
    }
}
